package com.example.mobilesafe.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;

import com.example.mobilesafe.dao.BlackNumberDao;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BlackNumberService extends Service {

    private InnerSmsReceiver mInnerSmsReceiver;

    private BlackNumberDao mDao;

    private TelephonyManager mSystemService;

    private MyPhoneStateListener mPhoneStateListener;

    private MyContentObserver mContentObserver;

    @Override
    public void onCreate() {
        super.onCreate();

        // 获取黑名单的数据操作类对象实例
        mDao = BlackNumberDao.getInstance(getApplicationContext());

        // 拦截短信
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        intentFilter.setPriority(1000); // 设置优先级
        mInnerSmsReceiver = new InnerSmsReceiver();
        registerReceiver(mInnerSmsReceiver,intentFilter);

        // 拦截电话
        mSystemService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        mPhoneStateListener = new MyPhoneStateListener();
        mSystemService.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    private class InnerSmsReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 1.获取短信内容，获取发送短信的电话号码，如果此电话号码在黑名单中，并且拦截模式也为1（短信）或3（所有），拦截短信
            Object[] pdus = (Object[])intent.getExtras().get("pdus");
            // 2.循环遍历短信的过程
            for (Object object : pdus) {
                // 3.获取短信对象
                SmsMessage sms = SmsMessage.createFromPdu((byte[]) object);
                // 4.获取短信对象的基本信息
                String originatingAddress = sms.getOriginatingAddress(); // 短信地址
                String messageBody = sms.getMessageBody(); // 短信内容
                // 5.使用黑名单的数据操作类操作数据
                int mode = mDao.queryModeByPhone(originatingAddress);
                if (mode == 1 || mode == 3){
                    // 拦截短信，即作为优先级最高的广播接受者拦截了“接收短信”的广播，该广播是有序广播
                    abortBroadcast();
                }
            }
        }
    }

    // 实现一个继承了PhoneStateListener的内部类
    class MyPhoneStateListener extends PhoneStateListener{
        // 手动重写，电话状态发生改变时会触发的方法
        @Override
        public void onCallStateChanged(int state, String phoneNumber) {
            super.onCallStateChanged(state, phoneNumber);
            switch (state){
                case TelephonyManager.CALL_STATE_IDLE:
                    // 空闲状态
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    // 摘机状态
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    // 响铃状态，电话关闭的api防到了aidl中
                    endCall(phoneNumber);
                    break;
            }
        }
    }

    /**
     * 挂断电话的方法
     * @param phoneNumber 要挂断的电话
     */
    private void endCall(String phoneNumber) {
        int mode = mDao.queryModeByPhone(phoneNumber);
        if (mode == 2 || mode == 3){
            // 拦截电话，由于ServiceManager此类Android对开发者隐藏，所以不能直接调用其方法，需要反射调用
            try {
                // 1.获取ServiceManger字节码文件
                Class<?> clazz = Class.forName("android.os.ServiceManager");
                // 2.获取反射方法
                Method method = clazz.getMethod("getService", String.class);
                // 3.反射调用此方法
                IBinder iBinder = (IBinder) method.invoke(null,Context.TELEPHONY_SERVICE);
                // 4.调用获取aidl文件对象方法
                // ITelePhoney iTelePhoney = ITelePhoney.stub.asInterface(iBinder);
                // 5.调用在aidl中隐藏的endcall方法
                // iTelePhoney.endCall();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            // 6.删除此被拦截的电话号码的通信记录（要加读写日志权限）（方式一）
            // getContentResolver().delete(Uri.parse("content://call_log/calls"),"number = ?",new String[]{phoneNumber});
            // 6.通过内容解析器去注册内容观察者，然后观察数据库的变化（方式二）
            mContentObserver = new MyContentObserver(new Handler(), phoneNumber);
            getContentResolver().registerContentObserver(Uri.parse("content://call_log/calls"),true,mContentObserver);
        }
    }

    /**
     * 自定义的ContentObserver类
     */
    private class MyContentObserver extends ContentObserver {

        private String phoneNumber;

        public MyContentObserver(Handler handler,String phoneNumber) {
            super(handler);
            this.phoneNumber = phoneNumber;
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            // 数据库中指定表在发生改变时会去调用的方法
            getContentResolver().delete(Uri.parse("content://call_log/calls"),"number = ?",new String[]{phoneNumber});
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 注销广播
        if (mInnerSmsReceiver != null){
            unregisterReceiver(mInnerSmsReceiver);
        }
        // 注销内容管擦着
        if (mContentObserver != null){
            getContentResolver().unregisterContentObserver(mContentObserver);
        }
        // 取消对电话状态的监听
        if (mPhoneStateListener != null){
            mSystemService.listen(mPhoneStateListener,PhoneStateListener.LISTEN_NONE);
        }
    }


}